package com.teach.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.hutool.core.convert.Convert;

/**
 * <pre>
 * - 给EL表达式使用的工具类
 * - 使用上下文监听器给上下文属性加入该对象 application.setAttribute("t",new ELTools());
 * - jsp中EL示例：${t.formatDate(date)}
 * ClassName : com.teach.commons.Tools
 * Author : J.L.Zhou
 * Tel : 15111047708
 * E-Mail : 12020042@qq.com
 * Date : 2020-10-31 19:28
 * Version : 1.0
 * </pre>
 */
@Component
public class ELTools {
	
	@Autowired
	private ObjectMapper objectMapper;

	private static ThreadLocal<SimpleDateFormat> format = ThreadLocal
			.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

	/**
	 * 格式化日期，格式：yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public String formatDate(Date date) {
		if (date == null) {
			return null;
		}
		return format.get().format(date);
	}

	public String formatDate(Date date, String format) {
		if (date == null) {
			return null;
		}
		return new SimpleDateFormat(format).format(date);
	}

	/**
	 * 四舍五入保留小数点
	 * 
	 * @param number
	 * @param len    - 保留小数点 位数
	 * @return
	 */
	public String formatNumber(BigDecimal number, int len) {
		if (number == null) {
			return null;
		}
		number = number.setScale(len, RoundingMode.HALF_UP);
		return number.toString();
	}

	/**
	 * 四舍五入保留小数点
	 * 
	 * @param number
	 * @param len    - 保留小数点 位数
	 * @return
	 */
	public String formatNumber(Float number, int len) {
		if (number == null) {
			return null;
		}
		return formatNumber(new BigDecimal(number), len);
	}

	/**
	 * 四舍五入保留小数点
	 * 
	 * @param number
	 * @param len    - 保留小数点 位数
	 * @return
	 */
	public String formatNumber(Double number, int len) {
		if (number == null) {
			return null;
		}
		return formatNumber(new BigDecimal(number), len);
	}

	public String formatNumber(String number, int len) {
		return formatNumber(new BigDecimal(number), len);
	}

	/**
	 * 四舍五入保留小数点
	 * 
	 * @param number
	 * @param len    - 保留小数点 位数
	 * @return
	 */
	public String formatNumber(double number, int len) {
		return formatNumber(new BigDecimal(number), len);
	}

	/**
	 * 中文金额
	 * 
	 * @param number
	 * @return
	 */
	public String formatChinese(BigDecimal number) {
		if (number == null) {
			return null;
		}
		number = number.setScale(2, RoundingMode.HALF_UP);
		return Convert.digitToChinese(number);
	}

	public String formatChinese(double number) {
		return Convert.digitToChinese(number);
	}

	public String formatChinese(Number number) {
		if (number == null) {
			return null;
		}
		return Convert.digitToChinese(number);
	}

	private String li = "<li data-page=\"{pageNumber}\" class=\"page-item{active}\"><a class=\"page-link\" href=\"{pageURL}\">{pageText}</a></li>";

	private String formatLi(boolean active, long pageNumber, String pageURL, String pageText) {
		return li.replace("{active}", active ? " active" : "").replace("{pageNumber}", pageNumber + "")
				.replace("{pageURL}", pageURL).replace("{pageText}", pageText);
	}

	/**
	 * 格式化分页页码
	 * 
	 * @param page
	 * @param max
	 * @param url  页码连接使用占位符{page}对应页码
	 * @return
	 */
	public String page(Page<?> page, int max, String url) {
		if (page == null || page.getTotal() == 0) {
			return null;
		}

		if (max < 2) {
			max = 2;
		}
		if (url == null) {
			url = "javascript:void(0);";
		}
		StringBuffer html = new StringBuffer("<ul class=\"pagination justify-content-center\">");

		long startNum = page.getCurrent()-max<1?1:page.getCurrent()-max;
		long endNum = page.getCurrent()+max>page.getPages()?page.getPages():page.getCurrent()+max;
		
		if (startNum > 1) {
			html.append(formatLi(false, 1, url.replace("{page}", "1"), "首页"));
		}
		for (long i=startNum;i<=endNum;i++) {
			html.append(formatLi(i==page.getCurrent(), i, url.replace("{page}",i+""), i+""));
		}
		if (endNum < page.getPages()) {
			html.append(formatLi(false, page.getPages(), url.replace("{page}", page.getPages()+""), "尾页"));
		}
		html.append("</ul>");
		return html.toString();
	}

	public String page(Page<?> page, int max) {
		return page(page, max, null);
	}

	public String page(Page<?> page, String url) {
		return page(page, 2, url);
	}

	public String page(Page<?> page) {
		return page(page, 2, null);
	}

	public String concat(String... strs) {
		if (strs == null) {
			return null;
		}
		return String.join("", strs);
	}

	@SuppressWarnings("unchecked")
	public List<String> toList(String str) {
		try {
			JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, String.class); 
			return (List<String>)objectMapper.readValue(str, javaType);
		} catch (Exception ex) {
			return null;
		}
	}

	/**
	 * - 截取前面部分字符串
	 * 
	 * @param str        - 要截取的字符串
	 * @param maxLen     - 要截取的最大长度
	 * @param removeHtml - 是否要移除字符串里面的html标签
	 * @return
	 */
	public String subStr(String str, int maxLen, boolean removeHtml) {
		if (str == null) {
			return null;
		}
		if (removeHtml) {
			str = str.replaceAll("<[^>]+>", "");
		}
		str = str.replaceAll("\\s", "");
		if (str.length() <= maxLen) {
			return str;
		} else {
			return str.substring(0, maxLen - 2) + "...";
		}
	}
}
